package com.wuhao.code.check.inspection.fix.kotlin

import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ReadAction.nonBlocking
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.refactoring.rename.RenameUtil
import com.intellij.usageView.UsageInfo
import com.wuhao.code.check.enums.NamingMethod
import com.wuhao.code.check.inspection.fix.BaseNameFix
import org.jetbrains.kotlin.psi.KtCallableDeclaration

/**
 * 重命名Kotlin元素（属性，方法）为驼峰命名
 * @author 吴昊
 */
class KotlinNameFix(namingMethod: NamingMethod) : BaseNameFix(namingMethod) {

  override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
    val namedElement = descriptor.psiElement.parent as KtCallableDeclaration
    val newName = getNewName(namedElement.name ?: return)


    // 正常模式：显示进度对话框
    ProgressManager.getInstance()
        .run(object : Task.Backgroundable(project, "正在重命名 ${namedElement.name} 为 $newName...", true) {

          override fun run(indicator: ProgressIndicator) {
            indicator.text = "查找引用..."
            indicator.fraction = 0.3

            val usages = nonBlocking<Array<UsageInfo>> {
              RenameUtil.findUsages(namedElement, newName, true, true, mapOf())
            }.executeSynchronously()

            if (usages != null) {
              indicator.text = "执行重命名..."
              indicator.fraction = 0.8

              ApplicationManager.getApplication().invokeLater({
                CommandProcessor.getInstance().executeCommand(project, {
                  ApplicationManager.getApplication().runWriteAction {
                    RenameUtil.doRename(namedElement, newName, usages, project, null)
                  }
                }, "Rename Element", null)
              }, ModalityState.defaultModalityState())
            }

            indicator.fraction = 1.0
          }

        })
  }

}
